import typing

class DataABC(object):
    '''
    Description:
        通用的Data对象
    '''
    def __init__(
        self,
        name: 'str',
        value: typing.Union['int', 'float', 'str', 'bytearray'] = 0,
        factor: 'float' = 1.0,
        offset: 'float' = 0.0,
        unit: 'str' = '') -> None:
        super().__init__()
        self._parent = None
        self._name = name
        self._children = dict()
        self._value = value
        self._factor = factor
        self._offset = offset
        self._unit = unit

    def Parent(self) -> typing.Union['DataABC', None]:
        '''
        Function：
            获取本Data的父Data
        '''
        return self._parent

    def Name(self) -> 'str':
        '''
        Function:
            获取本Data的名字
        '''
        return self._name

    def SetParent(self, parent: 'DataABC') -> None:
        '''
        Fucntion:
            设置本Data的父Data
        '''
        self._parent = parent

    def AddChild(self, child: 'DataABC') -> 'bool':
        '''
        Function:
            添加一个子Data
        '''
        if (child.Name() in self._children.keys()):
            return False
        self._children[child.Name()] = child
        child.SetParent(self)
        return True

    def RemoveChild(self, name: 'str') -> 'bool':
        '''
        Function:
            根据Child的名字移除指定Child
        '''
        if (name not in self._children.keys()):
            return False
        del self._children[name]
        return True
    
    def ClearChildren(self) -> None:
        '''
        Function:
            清除所有的子Data
        '''
        l_ = list(self._children.keys())
        for i_ in l_:
            self.RemoveChild(i_)
    
    @typing.overload
    def Get(self, path: 'list') -> typing.Union['DataABC', None]:
        ...
    @typing.overload
    def Get(self, path: 'str', split: 'str' = '.') -> typing.Union['DataABC', None]:
        ...
    def Get(self, *args) -> typing.Union['DataABC', None]:
        '''
        Function:
            获取指定的子Data
        args:
            path: 子Data的路径字符串 | 子Data的字符串List
            split: 路径的分隔符
        '''
        path_ = args[0]
        path_l_ = list()
        if (isinstance(path_, list)):
            # 入参是List
            path_l_ = path_
        elif (isinstance(path_, str)):
            split_ = args[1]
            path_l_ = path_.split(split_)
        if (len(path_l_) == 0):
            return self
        name_ = path_l_.pop(0)
        if (name_ not in self._children.keys()):
            return None
        child_ = self._children[name_]
        if (not isinstance(child_, DataABC)):
            return None
        return child_.Get(path_l_)
    
    def Property(self) -> 'dict':
        '''
        Function:
            获取本Data的属性
        '''
        return {
            'name': self.Name(),
            'factor': self._factor,
            'offset': self._offset,
        }

    def Export(self) -> 'dict':
        '''
        Function:
            导出本对象的参数
        '''
        property_ = self.Property()
        children_ = dict()
        for value_ in self._children.values():
            if (not isinstance(value_, DataABC)):
                continue
            children_.update({value_.Name(): value_.Export()})
        property_.update({'children': children_})
        return property_

    def Import(self, data: 'dict') -> None:
        '''
        Function:
            导入参数生成数据树
        '''
        name_ = data.get('name', None)
        if (not isinstance(name_, str)):
            return
        offset_ = data.get('offset', None)
        if (not isinstance(offset_, float)):
            return
        factor_ = data.get('factor', None)
        if (not isinstance(factor_, float)):
            return
        children_ = data.get('children', None)
        if (not isinstance(children_, dict)):
            return
        self._name = name_
        self._factor = factor_
        self._offset = offset_
        for name_, data_ in children_.items():
            if (not isinstance(name_, str)):
                continue
            if (not isinstance(data_, dict)):
                continue
            child_ = DataABC(name_)
            child_.Import(data_)
            self.AddChild(child_)
